#ifndef CUSTOM_RC_RAYMARCHING_INCLUDED
#define CUSTOM_RC_RAYMARCHING_INCLUDED

#include "RCCommon.hlsl"

// Uniform Parameter
uniform int Cascade_Level;                          // Current Cascade Level n
uniform float Cascade_Marching_Begin;               // Sample From [Cascade_MarchingLength_Base * pow(2, n)] To [Cascade_MarchingLength_Base * pow(2, n + 1)]
uniform float Cascade_Marching_End;                 // Sample From [Cascade_MarchingLength_Base * pow(2, n)] To [Cascade_MarchingLength_Base * pow(2, n + 1)]

uniform Texture2D _BlueNoiseTex;
SamplerState sampler_BlueNoiseTex;

#define RayMarchingCount 1

float4 RCRayMarchingFragment(Vert2Frag Input) : SV_TARGET {
    ProbeInfo Probe = GetProbeInfo(Cascade_Level, Input.ScreenUV);

    // Position
    float2 ProbePixPos = Probe.Probe * Probe.ProbeLength + Probe.ProbeLength / 2;

    // Angle
    float AngleLocalIndex   = Probe.AngleLocalPix.x + Probe.AngleLocalPix.y * Probe.AngleSize.x;
    const float NoiseFluence = 0.0f / RayMarchingCount;
    // Noise
    float2 NoiseUV = Input.ScreenUV;
    float Noise         = _BlueNoiseTex.Sample(sampler_BlueNoiseTex, NoiseUV).x;
    float NoiseAngle    = Noise * NoiseFluence * 2.0 - NoiseFluence;
    
    // Deal With Marching Result
    float4 Result = float4(0.0, 0.0, 0.0, 0.0);
    [unroll] 
    for (int RayMarchingIndex = 1; RayMarchingIndex <= RayMarchingCount; RayMarchingIndex++) {
        float   MarchingAngle   = ((AngleLocalIndex + RayMarchingIndex * 1.0 / (RayMarchingCount + 1) + NoiseAngle) / Probe.AngleSize.x / Probe.AngleSize.y) * 2 * PI;
        float2  MarchingDir     = float2(cos(MarchingAngle), sin(MarchingAngle));
        Result += RayMarching((ProbePixPos / _ScreenParams.y) + Cascade_Marching_Begin * MarchingDir, MarchingDir, Cascade_Marching_End - Cascade_Marching_Begin);
    }
    Result /= RayMarchingCount;

    // Result = float4(AngleLocalIndex / Probe.AngleSize.x / Probe.AngleSize.y, AngleLocalIndex / Probe.AngleSize.x / Probe.AngleSize.y, AngleLocalIndex / Probe.AngleSize.x / Probe.AngleSize.y, 1.0);
    // float a = (AngleLocalIndex / Probe.AngleSize.x / Probe.AngleSize.y) * 2 * PI;
    // if (a <= 0 || a >= 0.5 * PI)
    //     Result = float4(0, 0, 0, 1.0);
    // else
    //     Result = float4(1, 1, 1, 1.0);
    // Result = float4(1.0 * Probe.AngleLocalPix.x / Probe.AngleSize.x, 0.0, 0.0, 1.0);
    // Result = float4(Probe.TexPix.x % 4 / 4.0, Probe.TexPix.y % 4 / 4.0, 0.0, 1.0);
    // Result = float4(1.0 * Probe.TexPix / Probe.AngleSize, 0.0, 1.0);
    // Result = float4(1.0 / 6, 1.0 / 6, 1.0 / 6, 1.0);
    // Result = float4(ProbePixPos / _ScreenParams.xy, 0.0, 1.0);

    return Result;
}
#endif